/******************************************************************
 * Created by: DO HOANG HAI                                       
 * Date of Creation:                                               
 * Date of last modification: 13/Oct/2008
 * 
 * Modificator : Goh Chee Hong
 * Description: Provide global static method which performs shared 
 * functions or procedures.
 * 
 * Status: Optimized and finished
 ******************************************************************/

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Net;
using System.Runtime.InteropServices;
using System.IO;
using Org.BouncyCastle.Utilities.Encoders;
using System.Security.Cryptography;
namespace Pbdms.Common
{
    /// <summary>
    /// a class provides public function which can be accessed by any entity.
    /// </summary>
    [Flags]
    
    enum ConnectionState : int
    {
        INTERNET_CONNECTION_MODEM = 0x1,
        INTERNET_CONNECTION_LAN = 0x2,
        INTERNET_CONNECTION_PROXY = 0x4,
        INTERNET_RAS_INSTALLED = 0x10,
        INTERNET_CONNECTION_OFFLINE = 0x20,
        INTERNET_CONNECTION_CONFIGURED = 0x40
    }
    public class Global
    {
        public const string UNTRUSTED = "Untrusted";
        public const string TRUSTED = "Trusted";
        /// <summary>
        /// show message to inform user
        /// </summary>
        /// <param name="strMessage"></param>
        public static void showMsgOneButton(String strMessage, char c)
        {
            (new GUI.MsgBoxOneButton(strMessage, c)).ShowDialog();
        }

        /// <summary>
        /// dialog box with message and 2 options
        /// </summary>
        /// <param name="strMessage"></param>
        /// <param name="style"></param>
        /// <returns></returns>
        public static int showMsgTwoButtons(String strMessage, int style, char c)
        {
            GUI.MsgBoxTwoButtons msgConfirmation = new Common.GUI.MsgBoxTwoButtons(strMessage, style, c);
            msgConfirmation.ShowDialog();
            return msgConfirmation.returnValue;
        }

        /// <summary>
        /// dialog box with message and 3 options
        /// </summary>
        /// <param name="msg"></param>
        /// <returns></returns>
        public static int showMsgThreeButtons(String msg, char c)
        {
            GUI.MsgBoxThreeButtons msgConfirmation = new Common.GUI.MsgBoxThreeButtons(msg, c);
            msgConfirmation.ShowDialog();
            return msgConfirmation.returnValue;
        }

        /// <summary>
        /// paint the back ground of all the forms in the application
        /// </summary>
        /// <param name="frm"></param>
        public static void paintBackGround(System.Windows.Forms.Form frm)
        {
            frm.BackColor = Color.FromArgb(201, 213, 228);

            foreach (Control ctr in frm.Controls)
            {
                if (ctr.GetType().Equals(typeof(Label)) || ctr.GetType().Equals(typeof(CheckBox))
                    || ctr.GetType().Equals(typeof(RadioButton)) || ctr.GetType().Equals(typeof(TabPage))
                    || ctr.GetType().Equals(typeof(TabControl)) || ctr.GetType().Equals(typeof(Panel))
                    || ctr.GetType().Equals(typeof(GroupBox)) || ctr.GetType().Equals(typeof(PictureBox))
                    || ctr.GetType().Equals(typeof(StatusStrip)) || ctr.GetType().Equals(typeof(ToolStrip)))
                    ctr.BackColor = Color.FromArgb(201, 213, 228);

            }

        }

        /// <summary>
        /// get the index of the item with the text given in the dropdownlist (comboBox)
        /// </summary>
        /// <param name="ddl"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static int getDdlItemByStringValue(ComboBox ddl, string value)
        {
            if (ddl.Items.Count != 0)
            {
                for (int i = 0; i < ddl.Items.Count; i++)
                {
                    if (ddl.Items[i].ToString().ToLower().Equals(value.ToLower()))
                        return i;
                }
            }
            return -1;
        }
        /// <summary>
        /// copy a file locally or downloading from internet
        /// </summary>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        public static void copyFile(string source, string destination)
        {
            try
            {
                if (source.Contains("http"))
                {
                    //file is on local machine
                    //System.IO.File.Copy(source , destination , true);
                }
                //else if (isAnIPAddress(source))
                //{

                //}
                else
                {
                    //file is on local machine   
                    System.IO.File.Copy(source, destination, true);
                }
            }
            catch (Exception ex)
            {
                showMsgOneButton("Couldn't copy the file!\r\nError: " + ex.Message, 'C');
            }

        }

        /// <summary>
        /// download a file and save to a local address.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="destination"></param>
        public static void downloadFile(string source, string destination)
        {
            try
            {
                copyFile(source, destination);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// to test whether a string is in the format of an IP V4 address
        /// </summary>
        /// <param name="p"></param>
        /// <returns></returns>
        public static bool isAnIPAddress(string p)
        {
            //use regular expression to check whether this is an ipaddress
            /*
            string ifFormater = "^" +
              @"([01]?\d\d|2[0-4]\d|25[0-5])\." +
              @"([01]?\d\d|2[0-4]\d|25[0-5])\." +
              @"([01]?\d\d|2[0-4]\d|25[0-5])\." +
              @"([01]?\d\d|2[0-4]\d|25[0-5])" +
              "$";*/
            string ifFormater= @"\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b";
            //string ifFormater =  @"^([1-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\.
    //([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])){3}$";
            //Regex check = new Regex(ifFormater);
            Match ipMatcher = Regex.Match(p,ifFormater);//check.(p,0);
            return ipMatcher.Success;
        }
        /// <summary>
        /// get the startup path of the program
        /// </summary>
        /// <returns></returns>
        public static String startupPath()
        {
            return Application.StartupPath;
        }
        /// <summary>
        /// return default received file folder
        /// </summary>
        /// <returns></returns>
        public static String getReceivedFileFolder()
        {
            return Application.StartupPath+"\\Received Files\\";

        }
        /// <summary>
        /// show the form which report the list of errors
        /// </summary>
        /// <param name="arlItems"></param>
        /// <param name="title"></param>
        public static void showErrorReporter(ArrayList arlItems, String title)
        {
            (new GUI.FrmErrorReporter(arlItems, title)).ShowDialog();
        }

        /// <summary>
        /// construct a bibtex for a list of BibTex elements
        /// </summary>
        /// <param name="arlOfComponentBibTexStructs"></param>
        /// <returns></returns>
        public static string constructBibTex(ArrayList arlOfComponentBibTexStructs)
        {
            return (new BibTexConstructor(arlOfComponentBibTexStructs)).getBibTex();

        }
        /// <summary>
        /// get the address of the Library folder
        /// </summary>
        /// <returns></returns>
        public static string getLibFolder()
        {
            return startupPath() + "\\Library";
        }
        /// <summary>
        /// get the address of the tempfolder
        /// </summary>
        /// <returns></returns>
        public static string getTempFolder()
        {
            return startupPath() + "\\temp";
        }
        //get friends' keys
        public static string getKeyFolder()
        {
            return startupPath() + "\\Friends' public key";
        }
        public static string getPublishFolder()
        {
            return startupPath() + "\\publish";
        }
        // get all ip addressses associated with the system
        public static ArrayList getIPAddresses()
        {
            string hostName = Dns.GetHostName();
            IPHostEntry myself = Dns.GetHostEntry(hostName);
            ArrayList ret = new ArrayList();
            foreach (IPAddress address in myself.AddressList)
            {
                ret.Add(address);
            }

            return ret;
        }
        // get an ip address of the system
        public static IPAddress getIP()
        {
            string hostName = Dns.GetHostName();
            IPHostEntry myself = Dns.GetHostEntry(hostName);
            ArrayList ret = new ArrayList();
            foreach (IPAddress address in myself.AddressList)
            {
                if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    ret.Add(address);
                }
            }
            IPAddress ip = (IPAddress) ret[0];
            return ip;
        }
        //check whether the system is connected to the internet
        [DllImport("wininet.dll", CharSet = CharSet.Auto)]
        static extern bool InternetGetConnectedState(ref ConnectionState lpdwFlags, int dwReserved);
        public static Boolean getInternetstatus()
        {
            ConnectionState Description = 0;
            return InternetGetConnectedState(ref Description, 0);
              
        }


        //return a random string
        public static string RandomString()
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;
            for (int i = 0; i < 20; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            return builder.ToString();
        }

        //return a random number
        public static int RandomNumber()
        {
        
            Random random = new Random();
            int num = random.Next(10000);
            return num;
       
        }
        //convert to hex
        public static string convertFingerPrint(byte [] fingerPrint)
        {
            return Encoding.ASCII.GetString(Hex.Encode(fingerPrint));
        }
        //compute the hash sha-1
        public static string computeMessageDigest(string msg)
        {

            HashAlgorithm hashAlgorithm = SHA1.Create();
            hashAlgorithm.Initialize();
            byte [] msgBytes=hashAlgorithm.ComputeHash(GetBytes(msg));
            int [] bytesInt= new int[20];
            int i=0;
            string messageDigest = "";
            foreach (byte a in msgBytes)
            {
                
                bytesInt[i]=a;
                messageDigest = messageDigest + " " + bytesInt[i].ToString();
                i++;
            }

            return messageDigest;

        }
   
        //return in hexadecimal
        public static string computeMessageDigestHex(string msg)
        {

            HashAlgorithm hashAlgorithm = SHA1.Create();
            hashAlgorithm.Initialize();
            byte[] msgBytes = hashAlgorithm.ComputeHash(GetBytes(msg));
            int[] bytesInt = new int[20];
            int i = 0;
            string messageDigest = "";
            foreach (byte a in msgBytes)
            {

                bytesInt[i] = a;
                messageDigest = messageDigest + String.Format("{0:x2}", bytesInt[i]); ;
                i++;
            }

            return messageDigest;

        }


        //convert to bytes
        public static byte[] GetBytes(string str)
        {
            return Encoding.UTF8.GetBytes(str);
        }
        //convert to string
        public static string GetString(byte[] data)
        {
            string ret = string.Empty;
            try
            {
                ret = Encoding.UTF8.GetString(data);
            }
            catch { ret = string.Empty; }
            return ret;
        }
        
        public static string filterSignature(string msg)
        {
            string sign = msg;
            int startingpoint = sign.Trim().LastIndexOf(",");
            int j = sign.Length;
            int i=sign.Trim().Length;
            sign = sign.Substring(startingpoint + 1, sign.Trim().Length - startingpoint);
            /*
            string sign = msg.Trim().Substring(0,msg.Trim().LastIndexOf("'"));
            int startingpoint=sign.Trim().LastIndexOf("'");
            Console.WriteLine(sign.Length);

             */
            return sign;
        }
        public static string filterMsg(string msg)
        {
            
            string realmsg = msg.Trim().Substring(0, msg.Trim().LastIndexOf(","));

        
            
            return realmsg;
        }
         
        //filer unnecessary info RSS
        public static string filterPublicKey(string data)
        {
            int pos = data.IndexOf("(Public key:");
            string info = data.Substring(0, pos);
            return info;
        }
        //filtering RSS
        public static string filterUsername(string data)
        {
            int pos = data.IndexOf(":");
            string info = data.Substring(pos+1,data.Length-pos-2);
            return info;
        }
        //compute a sessionid based on now
        public static string computeSessionID()
        {
            DateTime dt = DateTime.Now;
            return (dt.Hour.ToString("00") + dt.Minute.ToString("00") + dt.Second.ToString("00"));
        }
        //translate file size to string
        public static string GetFileSize(long byteCount)
        {
            string size = "0 Bytes";
            if (byteCount >= 1073741824)
                size = String.Format("{0:##.##}", byteCount / 1073741824) + " GB";
            else if (byteCount >= 1048576)
                size = String.Format("{0:##.##}", byteCount / 1048576) + " MB";
            else if (byteCount >= 1024)
                size = String.Format("{0:##.##}", byteCount / 1024) + " KB";
            else if (byteCount > 0 && byteCount < 1024)
                size = byteCount.ToString() + " Bytes";

            return size;
        }
        public static string GetSmartFileSize(long byteCount)
        {
            string size = "0 Bytes";
            if (byteCount >= (1099511627776))
                size = String.Format("{0:##.##}", byteCount / 1073741824) + " GB";
            else if (byteCount >= 1073741824)
                size = String.Format("{0:##.##}", byteCount / 1048576) + " MB";
            else if (byteCount >= 1048576)
                size = String.Format("{0:##.##}", byteCount / 1024) + " KB";
            else if (byteCount > 0 && byteCount < 1048576)
                size = byteCount.ToString() + " Bytes";

            return size;
        }
        //filter size
        
        public static long filterSize(string msg)
        {
            int pos = msg.LastIndexOf(':');
            string sizeString = msg.Substring(pos + 1);
            long size = long.Parse(sizeString);
            return size;
        }
         
        /*
        public static int filterBlocks(string msg)
        {
            int pos = msg.LastIndexOf(':');
            string sizeString = msg.Substring(pos + 1);
            int size = int.Parse(sizeString);
            return size;
        }
         * */
        //filter the offline message key key
        public static string filerMailBoxKey(string msg)
        {
            int pos = msg.LastIndexOf("Size:");
            string mailKey = msg.Substring(0, pos - 1);
            return mailKey;
        }
        public static int CalculateNoOfBlocks(long size)
        {
            int blocks = (int)(size / 1024);
            int mod = (int)(size % 1024);
            if (mod != 0)
            {
                blocks++;
            }
            return blocks;
        }
    }
}